/*
 * downloader.cc
 *
 *  Created on: May 1, 2011
 *      Author: xrose
 */

#include "downloader.h"
#include <iostream>

downloader::downloader():
	_threadnum(),
	_thrTable(),
	_url(),
	_file(),
	_filename(){
	pthread_mutex_init(&fileLocker, NULL);
}
downloader::downloader(string url, int thrNum):	_threadnum(thrNum), _thrTable(thrNum), _url(url),_file(_url){

	cout<<"DEBUG: ...downloader::downloader("<<url<<", "<<thrNum<<")"<<endl;
	pthread_mutex_init(&fileLocker, NULL);
	_filename = _url.getIdentifier();
	cout<<"DEBUG: ...downloader::downloader::_filname"<<_filename<<endl;
	cout<<"DEBUG: ...downloader::downloader::_file.getSize() = "<<_file.getSize()<<endl;
	_file.open();

	//create thread record
	ulong fileSize = _file.getSize();
	ulong position = fileSize / _threadnum;
	ulong startByte = 0;

	for(int i=0; i<_threadnum; i++){
		ulong endByte = startByte + position;
		if(i==_threadnum-1){
			endByte = fileSize - 1;
		}
		cout<<"DEBUG: ...downloader::downloader::startByte = " <<startByte<<endl;
		cout<<"DEBUG: ...downloader::downloader::endByte = " <<endByte<<endl;
		thrdStruct threc(i, startByte, endByte);
		_thrTable.insert(threc);
		startByte = endByte + 1;
	}
	cout<<"DEBUG: ___downloader::downloader()"<<endl;
}
downloader::downloader(string url, int thrNum, string filename):
		_threadnum(thrNum), _thrTable(thrNum),
		_url(url),_file(_url), _filename(filename){
	pthread_mutex_init(&fileLocker, NULL);

	_file.open();

	//create thread record
	ulong fileSize = _file.getSize();
	ulong position = fileSize / _threadnum;
	ulong startByte = 0;

	for(int i=0; i<_threadnum; i++){
		ulong endByte = startByte+position;
		if(i==_threadnum-1){
			endByte = fileSize - 1;
		}
		thrdStruct threc(i, startByte, endByte);
		startByte = endByte + 1;
	}
}
downloader::~downloader(){
	_file.close();
	pthread_mutex_destroy(&fileLocker);
}
bool downloader::saveFile(){
	return _file.close();
}
bool downloader::downloadThreadId(int threadId){
	cout<<"DEBUG: ...downloader::downloadThreadId():threadId ="<<threadId<<endl;
	ulong receiveByte;
	thrdStruct *threc = _thrTable.getRecordHandle(threadId);
	uint cap = _thrTable.getCapacity();
	uint siz = _thrTable.getSize();
	cout<<"DEBUG: ..downloader::downloadThreadId():Size = "<<siz<<endl;
	cout<<"DEBUG: ..downloader::downloadThreadId():Capacity = "<<cap<<endl;
	cout<<"DEBUG: ..downloader::downloadThreadId():threadId ="<<threadId<<endl;
	cout<<"DEBUG: ..downloader::downloadThreadId(): url:port="<<_url.getPort()<<endl;
	cout<<"DEBUG: ..downloader::downloadThreadId(): url:host="<<_url.getHostname()<<endl;
	cout<<"DEBUG: ..downloader::downloadThreadId(): url:id="<<_url.getIdentifier()<<endl;

	httpConnections conn(threadId, _url);
	ulong stByte = threc->getStByte();
	ulong enByte = threc->getEndByte();
	ulong dledByte = threc->getDledByte();
	conn.sendGetRange(stByte, enByte);

	do{
		receiveByte = conn.receiveData(*threc);
		pthread_mutex_lock(&fileLocker);
		_file.write(*threc);
		pthread_mutex_unlock(&fileLocker);
		if(dledByte >= stByte-enByte + 1){
			conn.close();
		}
	} while (receiveByte > 0);
	cout<<"DEBUG: ___downloader::downloadThreadId()"<<endl;
	return true;
}
